`timescale 1ns/1ps
`include "Func.v"
module polyminalMultiplier#(parameter latency = 6 , parameter RAM_WIDTH  =96 ) //流水线延迟周�?
(
    input  wire clk,rst_n,Start,
    input  wire [5:0] func,
    input  wire [2:0] RAM_CTR, //RAM 源块、目的块选择  2:rs1 1:rs2 0:dst   bit 0 : RAM1 bit 1 : RAM2
    input  wire [RAM_WIDTH-1:0] R1_DoutA,R1_DoutB,R2_DoutA,R2_DoutB,
//    input  wire Compare_cnt_fresh,
    output wire Finish,
//    output reg  [7:0] Compare_cnt,
    output reg  [RAM_WIDTH-1:0] R1_DinA,R1_DinB,R2_DinA,R2_DinB,
    output wire R2_ena,R2_enb,R1_ena,R1_enb,
    output wire R2_wea,R2_web,R1_wea,R1_web,
    output wire [4:0] R2_AddrAL,R2_AddrBL,
    output wire [4:0] R1_AddrAL,R1_AddrBL,
    
    //debug 信号
    output wire [2:0] NTT_floor,
    output wire NTT_busy,
    output reg  InFuncPrintRAM
    
    );

wire [11:0] out0[0:3];
wire [11:0] out1[0:3];
wire [11:0] out2[0:3];
wire [11:0] out3[0:3];

//*************************  NTT 地址产生�? 信号 *************************//
    reg   NTT_Start,NTT_R_Ctr;
    wire  NTT_Finish,INTT,NTT_Mode;
    
    wire [4:0] NTT_R1_AddrAL,NTT_R1_AddrBL,NTT_R2_AddrAL,NTT_R2_AddrBL;
    wire NTT_R1_ena,NTT_R1_enb,NTT_R2_ena,NTT_R2_enb,NTT_R1_wea,NTT_R1_web,NTT_R2_wea,NTT_R2_web;
    
    wire NTT_twiddle_reverse;
    wire [6: 0] NTT_Addr_twiddle0,NTT_Addr_twiddle1,NTT_Addr_twiddle2,NTT_Addr_twiddle3;

    assign NTT_Mode = (func== `INTT) ? 1'b1 : 1'b0; //NTT_Mode
    always@(posedge clk or negedge rst_n) begin //NTT_Start 信号
        if(!rst_n) NTT_Start<=0;
        else if((func==`NTT || func==`INTT) & Start & ~NTT_busy) NTT_Start<=1;
        else NTT_Start<=0;
    end
    always@(posedge clk or negedge rst_n) begin //NTT_R_Ctr信号
        if(!rst_n) NTT_R_Ctr<=0;
        else if((func==`NTT || func==`INTT) & Start & ~NTT_busy) NTT_R_Ctr <= RAM_CTR[0];  //RAM_CTR == 001 RAM2->RAM1  100: RAM1->RAM2
        else if(NTT_busy & NTT_Finish) NTT_R_Ctr<=0;
    end

NTT_Addr_Gen #(.latency (8)) theNTT_Addr_Gen(
    .clk(clk),.rst_n(rst_n),
    .start(NTT_Start), .NTT_Mode(NTT_Mode),.R_Ctr(NTT_R_Ctr),
    .finish(NTT_Finish),.busy(NTT_busy),
    .floor_cnt(NTT_floor),   
    .R1_AddrA(NTT_R1_AddrAL),.R1_AddrB(NTT_R1_AddrBL),
    .R2_AddrA(NTT_R2_AddrAL),.R2_AddrB(NTT_R2_AddrBL),
    .R1_ena(NTT_R1_ena),.R1_enb(NTT_R1_enb),.R2_ena(NTT_R2_ena),.R2_enb(NTT_R2_enb),
    .R1_wea(NTT_R1_wea),.R1_web(NTT_R1_web),.R2_wea(NTT_R2_wea),.R2_web(NTT_R2_web),
    .twiddle_reverse(NTT_twiddle_reverse),
    .Addr_twiddle0(NTT_Addr_twiddle0), .Addr_twiddle1(NTT_Addr_twiddle1),.Addr_twiddle2(NTT_Addr_twiddle2),.Addr_twiddle3(NTT_Addr_twiddle3));
    assign INTT = NTT_twiddle_reverse;
//**********************************************************************//


//********************************** shift m **********************************//
wire Dot_busy;

wire [63:0] EncDin;
wire [95:0] DecDin;
wire Shift,Load;
wire [95:0] EncDout;
wire [63:0] DecDout;
assign EncDin = R2_DoutA[95:0];
assign DecDin = {out3[1],out3[0],out2[1],out2[0],out1[1],out1[0],out0[1],out0[0]};
assign Shift  = (func==`Encode_ADD ) & R1_AddrAL[2:0] != 3'b001 ||((func == `Decode_SUB)& Dot_busy);
assign Load   = (func==`Encode_ADD ) & R1_AddrAL[2:0] == 3'b001;


Shiftm theshiftm(.clk(clk),.rst_n(rst_n),
.EncDin(EncDin), //encode 并行输入
.DecDin(DecDin), //decode 串行输入
.Shift(Shift),.Load(Load),   //移位和并行加载控�? 
.EncDout(EncDout),//encode   0�?0 1�?1665
.DecDout(DecDout) 
);




//****************************************************************************//



//**********************************Dot 地址产生信号***********************//

reg Dot_Start;
always@(posedge clk or negedge rst_n) begin //NTT_Start 信号
    if(!rst_n) Dot_Start<=1'b0;
    else if((func!=`NTT & func!=`INTT) & Start & ~NTT_busy) Dot_Start<=1'b1;
    else Dot_Start<=1'b0;
end

wire [4:0] DOT_R1_AddrAL,DOT_R1_AddrBL,DOT_R2_AddrAL,DOT_R2_AddrBL;
wire DOT_R1_ena,DOT_R1_enb,DOT_R2_ena,DOT_R2_enb,DOT_R1_wea,DOT_R1_web,DOT_R2_wea,DOT_R2_web;
wire Dot_Finish;
wire [6:0]Dot_Addr_Twiddle0,Dot_Addr_Twiddle1,Dot_Addr_Twiddle2,Dot_Addr_Twiddle3;
Dot_Addr_Gen #(.max_latency(9))  theDot_Addr_Gen //不同运算延迟不同
(
    .clk(clk),.rst_n(rst_n),.Start(Dot_Start),
    .opcode(func),
    .RAM_CTR(RAM_CTR),
    .Finish(Dot_Finish), 
    .busy(Dot_busy),
    .R1_AddrAL(DOT_R1_AddrAL),.R1_AddrBL(DOT_R1_AddrBL),
    .R2_AddrAL(DOT_R2_AddrAL),.R2_AddrBL(DOT_R2_AddrBL),
    .R1_ena(DOT_R1_ena),.R1_enb(DOT_R1_enb),.R2_ena(DOT_R2_ena),.R2_enb(DOT_R2_enb),
    .R1_wea(DOT_R1_wea),.R1_web(DOT_R1_web),.R2_wea(DOT_R2_wea),.R2_web(DOT_R2_web),
    .Addr_twiddle0(Dot_Addr_Twiddle0),.Addr_twiddle1(Dot_Addr_Twiddle1),
    .Addr_twiddle2(Dot_Addr_Twiddle2),.Addr_twiddle3(Dot_Addr_Twiddle3)
);
//**********************************************************************//



//************************** 旋转因子 ****************************************//
wire [11:0] twiddle[0:3];
wire [11:0] ROM_out0,ROM_out1,ROM_out2,ROM_out3;
wire [ 6:0] Addr_twiddle0,Addr_twiddle1,Addr_twiddle2,Addr_twiddle3;

assign Addr_twiddle0 = NTT_busy? NTT_Addr_twiddle0 : Dot_Addr_Twiddle0;
assign Addr_twiddle1 = NTT_busy? NTT_Addr_twiddle1 : Dot_Addr_Twiddle1;
assign Addr_twiddle2 = NTT_busy? NTT_Addr_twiddle2 : Dot_Addr_Twiddle2;
assign Addr_twiddle3 = NTT_busy? NTT_Addr_twiddle3 : Dot_Addr_Twiddle3;

ConstantData ROM(
    .clk(clk), .rst_n(rst_n),
    .Addr_twiddle0(Addr_twiddle0),.Addr_twiddle1(Addr_twiddle1),.Addr_twiddle2(Addr_twiddle2),.Addr_twiddle3(Addr_twiddle3),
    .out0(ROM_out0),.out1(ROM_out1),.out2(ROM_out2),.out3(ROM_out3)
);
    wire twiddle_oppsite;
    assign twiddle_oppsite = (NTT_twiddle_reverse & NTT_busy) ;
    assign twiddle[0] = twiddle_oppsite? (12'd3329 - ROM_out0):ROM_out0;
    assign twiddle[1] = twiddle_oppsite || (func == `PWM2)? (12'd3329 - ROM_out1):ROM_out1;
    assign twiddle[2] = twiddle_oppsite? (12'd3329 - ROM_out2):ROM_out2;
    assign twiddle[3] = twiddle_oppsite || (func == `PWM2)? (12'd3329 - ROM_out3):ROM_out3;
//**********************************************************************//


//*************************** ALU **************************************//
reg  [23:0] ALU_a[0:3],ALU_b[0:3],ALU_w[0:3],ALU_c[0:3];
wire [ 5:0] ALU_op;
wire [47:0] Dout[0:3];

genvar i ; 

wire [11:0] R1_A[0:7],R1_B[0:7],R2_A[0:7],R2_B[0:7];
generate
    for(i=0;i<8;i=i+1)
    begin
       assign R1_A[i] = R1_DoutA[12*i + 11 : 12*i];
       assign R1_B[i] = R1_DoutB[12*i + 11 : 12*i];
       assign R2_A[i] = R2_DoutA[12*i + 11 : 12*i];
       assign R2_B[i] = R2_DoutB[12*i + 11 : 12*i];
    end
    endgenerate


//ALU相关输入信号
generate
    for(i=0;i<4;i=i+1) begin
        always@(posedge clk or negedge rst_n) begin
            if(!rst_n) begin
                ALU_a[i] <= 24'd0;
                ALU_b[i] <= 24'd0;
                ALU_c[i] <= 24'd0;
                ALU_w[i] <= 24'd0;
            end
        else begin
            //处于NTT  NTT_R_Ctr  1: R2 -> R1
            if(NTT_busy) 
            begin
                ALU_c[i] <= 24'd0;
                ALU_w[i] <= {twiddle[i],twiddle[i]};
                //处于 NTT �? 非第5�?6�?  或�?�处于INTT的非�?0�?1�?
                if((~INTT & ((NTT_floor !=3'd6) & (NTT_floor !=3'd5)) ) | (INTT & (NTT_floor !=3'd0) & (NTT_floor != 3'd1))) begin   
                    ALU_a[i] <= NTT_R_Ctr ^ NTT_floor[0] ? R2_DoutA[24*i+23 : 24*i] : R1_DoutA[24*i+23 : 24*i];
                    ALU_b[i] <= NTT_R_Ctr ^ NTT_floor[0] ? R2_DoutB[24*i+23 : 24*i] : R1_DoutB[24*i+23 : 24*i];
                end
                //NTT �?5�?  或�?? INTT �?1�?
                else if((~INTT & (NTT_floor == 3'd5)) | (INTT & (NTT_floor ==3'd1))) begin
                    if(i<2) begin 
                        ALU_a[i] <= NTT_R_Ctr ? R1_DoutA[24*i+23 : 24*i]    : R2_DoutA[24*i+23 : 24*i]   ;
                        ALU_b[i] <= NTT_R_Ctr ? R1_DoutA[24*i+71 : 24*i+48] : R2_DoutA[24*i+71 : 24*i+48];
                    end
                    else begin
                        ALU_a[i] <= NTT_R_Ctr ? R1_DoutB[24*(i-2)+23 : 24*(i-2)]    : R2_DoutB[24*(i-2)+23 : 24*(i-2)]   ;
                        ALU_b[i] <= NTT_R_Ctr ? R1_DoutB[24*(i-2)+71 : 24*(i-2)+48] : R2_DoutB[24*(i-2)+71 : 24*(i-2)+48];
                    end
                end
                //NTT �?6�?  或�?? INTT �?0�?
                else if((~INTT & (NTT_floor == 3'd6)) | (INTT & (NTT_floor ==3'd0))) begin
                    if(i<2) begin 
                        ALU_a[i] <= NTT_R_Ctr ? R2_DoutA[48*i+23 : 48*i]    : R1_DoutA[48*i+23 : 48*i]   ;
                        ALU_b[i] <= NTT_R_Ctr ? R2_DoutA[48*i+47 : 48*i+24] : R1_DoutA[48*i+47 : 48*i+24];
                    end
                    else begin
                        ALU_a[i] <= NTT_R_Ctr ? R2_DoutB[48*(i-2)+23 : 48*(i-2)]    : R1_DoutB[48*(i-2)+23 : 48*(i-2)]   ;
                        ALU_b[i] <= NTT_R_Ctr ? R2_DoutB[48*(i-2)+47 : 48*(i-2)+24] : R1_DoutB[48*(i-2)+47 : 48*(i-2)+24];
                    end
                end
                else begin
                    ALU_a[i] <= 24'd0;
                    ALU_b[i] <= 24'd0;
                    ALU_c[i] <= 24'd0;
                    ALU_w[i] <= 24'd0;
                end
            end
            else  begin
            case(func) 
            `PWM1:   //PWM2
                begin
                    if(RAM_CTR == `R2_TO_R1) //RAM2 -> RAM1 
                    begin
                        ALU_a[i] <= {R2_A[2*i],R2_B[2*i+1]  };//s A
                        ALU_b[i] <= {R2_A[2*i+1]  ,R2_B[2*i]};
                        ALU_c[i] <= 24'd0;
                        ALU_w[i] <= {R2_B[2*i+1]  ,R2_A[2*i]};
                    end
                    else 
                    begin //RAM1 -> RAM2 
                        ALU_a[i] <= {R1_A[2*i],R1_B[2*i+1]  };
                        ALU_b[i] <= {R1_A[2*i+1]  ,R1_B[2*i]};
                        ALU_c[i] <= 24'd0;
                        ALU_w[i] <= {R1_B[2*i+1]  ,R1_A[2*i]};
                    end
                end
            `PWM2: //PWM2
            begin
                if(RAM_CTR == `R2_TO_R1) //RAM2 -> RAM1 
                begin
                    ALU_a[i] <= {R2_B[2*i]  ,R2_B[2*i]  };
                    ALU_b[i] <= {R2_A[2*i]  ,R2_B[2*i+1]};
                    ALU_c[i] <= {R2_B[2*i+1],12'd0};
                    ALU_w[i] <= {R2_A[2*i+1],twiddle[i] };
                end
                else 
                begin //RAM1 -> RAM2 
                    ALU_a[i] <= {R1_B[2*i]  ,R1_B[2*i]  };
                    ALU_b[i] <= {R1_A[2*i]  ,R1_B[2*i+1]};
                    ALU_c[i] <= {R1_B[2*i+1],12'd0};
                    ALU_w[i] <= {R1_A[2*i+1],twiddle[i] };
                end
            end 
            `PolyAdd: //PolyAdd
            begin
                ALU_w[i] <= 24'd0; ALU_c[i] <= 24'd0;
                case(RAM_CTR)
                3'b001:          begin ALU_a[i] <= {R2_A[2*i+1],R2_A[2*i]}; ALU_b[i] <= {R2_B[2*i+1]  ,R2_B[2*i]}; end
                3'b101 , 3'b011: begin ALU_a[i] <= {R1_B[2*i+1],R1_B[2*i]}; ALU_b[i] <= {R2_B[2*i+1]  ,R2_B[2*i]}; end
                3'b110:          begin ALU_a[i] <= {R1_A[2*i+1],R1_A[2*i]}; ALU_b[i] <= {R1_B[2*i+1]  ,R1_B[2*i]}; end
                3'b100 , 3'b010: begin ALU_a[i] <= {R1_B[2*i+1],R1_B[2*i]}; ALU_b[i] <= {R2_B[2*i+1]  ,R2_B[2*i]}; end
                default :begin ALU_a[i] <= 24'd0; ALU_b[i] <= 24'd0; end
                endcase
            end
            `Encode_ADD: //Encode_ADD
            begin
                ALU_a[i] <= {R1_A[2*i+1],R1_A[2*i]};
                ALU_b[i] <= EncDout[24*i+23 : 24*i];
                //ALU_b[i] = 24'd0;
                ALU_c[i] <= {R1_B[2*i+1],R1_B[2*i]};
                ALU_w[i] <= 24'd1;
            end
            `Decode_SUB: //Decode_sub
            begin
                ALU_a[i] <= {R1_B[2*i+1],R1_B[2*i]};
                ALU_b[i] <= {R2_B[2*i+1],R2_B[2*i]};
                //ALU_b[i] = 24'd0;
                ALU_c[i] <= 24'd0;
                ALU_w[i] <= 24'd0;
            end
            `Compress10,`Compress4,`Decompress10,`Decompress4,`Compress11,`Compress5,`Decompress11,`Decompress5:
            begin
                if(RAM_CTR == `R2_TO_R1) //RAM2 -> RAM1 
                begin
                    ALU_a[i] <= {R2_A[2*i+1]  ,R2_A[2*i]  };
                    ALU_b[i] <= 24'd0;
                    ALU_c[i] <= 24'd0;
                    ALU_w[i] <= 24'd0;
                end
                else 
                begin //RAM1 -> RAM2 
                    ALU_a[i] <= {R1_A[2*i+1]  ,R1_A[2*i]  };
                    ALU_b[i] <= 24'd0;
                    ALU_c[i] <= 24'd0;
                    ALU_w[i] <= 24'd0;
                end
            end
            default:
            begin
                ALU_a[i] <= 24'd0;
                ALU_b[i] <= 24'd0;
                ALU_c[i] <= 24'd0;
                ALU_w[i] <= 24'd0;
            end
            endcase
            end
        end
        end
    end
    endgenerate

assign ALU_op = func;





// //实例化ALU
// generate   
//     for(i=0;i<4;i=i+1)  
//     begin : ALU
//          ALU  thealu( .clk(clk), .rst_n(rst_n), .ain(ALU_a[i]),.bin(ALU_b[i]),.cin(ALU_c[i]),.win(ALU_w[i]),.opcode(ALU_op), .Dout(Dout[i]));
//     end
// endgenerate
PLU  thealu0( .clk(clk), .rst_n(rst_n), .ain(ALU_a[0]),.bin(ALU_b[0]),.cin(ALU_c[0]),.win(ALU_w[0]),.opcode(ALU_op), .Dout(Dout[0]));
PLU  thealu1( .clk(clk), .rst_n(rst_n), .ain(ALU_a[1]),.bin(ALU_b[1]),.cin(ALU_c[1]),.win(ALU_w[1]),.opcode(ALU_op), .Dout(Dout[1]));
PLU  thealu2( .clk(clk), .rst_n(rst_n), .ain(ALU_a[2]),.bin(ALU_b[2]),.cin(ALU_c[2]),.win(ALU_w[2]),.opcode(ALU_op), .Dout(Dout[2]));
PLU  thealu3( .clk(clk), .rst_n(rst_n), .ain(ALU_a[3]),.bin(ALU_b[3]),.cin(ALU_c[3]),.win(ALU_w[3]),.opcode(ALU_op), .Dout(Dout[3]));

//************************* Comprare ******************************//
// reg Compare_busy;
// always@(posedge clk or negedge rst_n) 
// begin
//     if(!rst_n) Compare_busy<=1'b0;
//     else if((func == `Compare11 || func==`Compare10 || func == `Compare4 || func == `Compare5) && DOT_R1_AddrAL == 5'd2)  Compare_busy<=1'b1; //对时序的 别问
//     else if((func == `Compare11 || func==`Compare10 || func == `Compare4 || func == `Compare5) && Finish) Compare_busy<=1'b0;
// end


// always @(posedge clk or negedge rst_n) 
// begin
//     if(!rst_n) Compare_cnt<=8'd0;    
//     else if(Compare_cnt_fresh) Compare_cnt<=8'd0;
//     else if(Compare_busy && (Dout[0][23:0]==24'h001001) && (Dout[1][23:0]==24'h001001) &&(Dout[2][23:0]==24'h001001) && (Dout[3][23:0]==24'h001001)) Compare_cnt <= Compare_cnt+1'b1;
// end



//******************************************************************//

//**************************** 输出转换 *****************************//

generate
    for(i=0;i<2;i=i+1) begin
        assign out0[i]   = Dout[0][12*i+11 : 12*i   ];
        assign out0[i+2] = Dout[0][12*i+35 : 12*i+24];
        assign out1[i]   = Dout[1][12*i+11 : 12*i   ];
        assign out1[i+2] = Dout[1][12*i+35 : 12*i+24];
        assign out2[i]   = Dout[2][12*i+11 : 12*i   ];
        assign out2[i+2] = Dout[2][12*i+35 : 12*i+24];
        assign out3[i]   = Dout[3][12*i+11 : 12*i   ];
        assign out3[i+2] = Dout[3][12*i+35 : 12*i+24];
    end
endgenerate
//*********************************************************************//

//************************  输出  *************************************//

always@(posedge clk or negedge rst_n) begin
    if(!rst_n) begin
        R1_DinA <= 96'd0;
        R1_DinB <= 96'd0;
        R2_DinA <= 96'd0;
        R2_DinB <= 96'd0;
    end
// always@(*) begin
    else if(NTT_busy) begin //处于NTT
        //处于 NTT 的非�?5�?6�?  或�?�处于INTT的非�?0�?1�?
        if((~INTT & ((NTT_floor !=3'd6) & (NTT_floor !=3'd5)) ) | (INTT & (NTT_floor !=3'd0) & (NTT_floor != 3'd1))) 
        begin    
            R1_DinA <= {out3[1],out3[0],out2[1],out2[0],out1[1],out1[0],out0[1],out0[0]};
            R1_DinB <= {out3[3],out3[2],out2[3],out2[2],out1[3],out1[2],out0[3],out0[2]};
            R2_DinA <= {out3[1],out3[0],out2[1],out2[0],out1[1],out1[0],out0[1],out0[0]};
            R2_DinB <= {out3[3],out3[2],out2[3],out2[2],out1[3],out1[2],out0[3],out0[2]};
        end
        //NTT �?5�?  或�?? INTT �?1�?
        else if((~INTT & (NTT_floor == 3'd5)) | (INTT & (NTT_floor ==3'd1))) begin
            R1_DinA <= {out1[3],out1[2],out0[3],out0[2],out1[1],out1[0],out0[1],out0[0]};
            R1_DinB <= {out3[3],out3[2],out2[3],out2[2],out3[1],out3[0],out2[1],out2[0]};
            R2_DinA <= {out1[3],out1[2],out0[3],out0[2],out1[1],out1[0],out0[1],out0[0]};
            R2_DinB <= {out3[3],out3[2],out2[3],out2[2],out3[1],out3[0],out2[1],out2[0]};
        end
        //NTT �?6�?  或�?? INTT �?0�?
        else if((~INTT & (NTT_floor == 3'd6)) | (INTT & (NTT_floor ==3'd0))) begin
            R1_DinA <= {out1[3],out1[2],out1[1],out1[0],out0[3],out0[2],out0[1],out0[0]};
            R1_DinB <= {out3[3],out3[2],out3[1],out3[0],out2[3],out2[2],out2[1],out2[0]};
            R2_DinA <= {out1[3],out1[2],out1[1],out1[0],out0[3],out0[2],out0[1],out0[0]};
            R2_DinB <= {out3[3],out3[2],out3[1],out3[0],out2[3],out2[2],out2[1],out2[0]};
        end
        else begin
            R1_DinA <= 96'd0;
            R1_DinB <= 96'd0;
            R2_DinA <= 96'd0;
            R2_DinB <= 96'd0;
        end
    end
    else begin
    case (func)
        `PWM1:
        begin
            R1_DinA <= {out3[1],out3[0],out2[1],out2[0],out1[1],out1[0],out0[1],out0[0]};
            R1_DinB <= {out3[3],out3[2],out2[3],out2[2],out1[3],out1[2],out0[3],out0[2]};
            R2_DinA <= {out3[1],out3[0],out2[1],out2[0],out1[1],out1[0],out0[1],out0[0]};
            R2_DinB <= {out3[3],out3[2],out2[3],out2[2],out1[3],out1[2],out0[3],out0[2]};
        end
        `PWM2:
        begin
            R1_DinA <= {out3[3],out3[0],out2[3],out2[0],out1[3],out1[0],out0[3],out0[0]};
            R1_DinB <= 96'd0;
            R2_DinA <= {out3[3],out3[0],out2[3],out2[0],out1[3],out1[0],out0[3],out0[0]};
            R2_DinB <= 96'd0;
        end
        `PolyAdd:
        begin
            R1_DinA <= {out3[1],out3[0],out2[1],out2[0],out1[1],out1[0],out0[1],out0[0]};
            R1_DinB <= 96'd0;
            R2_DinA <= {out3[1],out3[0],out2[1],out2[0],out1[1],out1[0],out0[1],out0[0]};
            R2_DinB <= 96'd0;
        end
        `Encode_ADD:
        begin
            R1_DinA <= 96'd0;
            R1_DinB <= 96'd0;
            R2_DinA <= 96'd0;
            R2_DinB <= {out3[1],out3[0],out2[1],out2[0],out1[1],out1[0],out0[1],out0[0]};
        end
        `Decode_SUB:
        begin
            R1_DinA <= {32'd0,DecDout[63:0]};
            R1_DinB <= 96'd0;
            R2_DinA <= 96'd0;
            R2_DinB <= 96'd0;
        end
        `Compress10,`Compress4,`Decompress10,`Decompress4,`Compress11,`Compress5,`Decompress11,`Decompress5:
        begin
            R1_DinA <= {out3[1],out3[0],out2[1],out2[0],out1[1],out1[0],out0[1],out0[0]};
            R1_DinB <= 96'd0;
            R2_DinA <= {out3[1],out3[0],out2[1],out2[0],out1[1],out1[0],out0[1],out0[0]};
            R2_DinB <= 96'd0;
        end
        default:
        begin
            R1_DinA <= 96'd0;
            R1_DinB <= 96'd0;
            R2_DinA <= 96'd0;
            R2_DinB <= 96'd0;
        end
    endcase
    end
end

//*********************************************************************//
//RAM en信号
// always@(posedge clk or negedge rst_n) begin
//     if(!rst_n) begin
//         R1_ena= 1'b0;
//         R1_enb= 1'b0;
//         R2_ena= 1'b0;
//         R2_enb= 1'b0;
//     end
//     else begin
//         R1_ena= (NTT_busy ? NTT_R1_ena : DOT_R1_ena);
//         R1_enb= (NTT_busy ? NTT_R1_enb : DOT_R1_enb);
//         R2_ena= (NTT_busy ? NTT_R2_ena : DOT_R2_ena);
//         R2_enb= (NTT_busy ? NTT_R2_enb : DOT_R2_enb);
//     end
// end

// //RAM we信号
// always@(posedge clk or negedge rst_n) begin
//     if(!rst_n) begin
//         R1_wea= 1'b0;
//         R1_web= 1'b0;
//         R2_wea= 1'b0;
//         R2_web= 1'b0;
//     end
//     else begin
//         R1_wea= (NTT_busy ? NTT_R1_wea : DOT_R1_wea);
//         R1_web= (NTT_busy ? NTT_R1_web : DOT_R1_web);
//         R2_wea= (NTT_busy ? NTT_R2_wea : DOT_R2_wea);
//         R2_web= (NTT_busy ? NTT_R2_web : DOT_R2_web);
//     end
// end

// //RAM AddrL
// always@(posedge clk or negedge rst_n) begin
//     if(!rst_n) begin
//         R1_AddrAL= 5'b0;
//         R1_AddrBL= 5'b0;
//         R2_AddrAL= 5'b0;
//         R2_AddrBL= 5'b0;
//     end
//     else begin
//         R1_AddrAL= (NTT_busy ? NTT_R1_AddrAL :DOT_R1_AddrAL);
//         R1_AddrBL= (NTT_busy ? NTT_R1_AddrBL :DOT_R1_AddrBL);
//         R2_AddrAL= (NTT_busy ? NTT_R2_AddrAL :DOT_R2_AddrAL);
//         R2_AddrBL= (NTT_busy ? NTT_R2_AddrBL :DOT_R2_AddrBL);
//     end
// end
//******************RAM 信号*******************//


assign R1_ena= (NTT_busy ? NTT_R1_ena : DOT_R1_ena);
assign R1_enb= (NTT_busy ? NTT_R1_enb : DOT_R1_enb);
assign R2_ena= (NTT_busy ? NTT_R2_ena : DOT_R2_ena);
assign R2_enb= (NTT_busy ? NTT_R2_enb : DOT_R2_enb);

//RAM we信号
assign R1_wea= (NTT_busy ? NTT_R1_wea : DOT_R1_wea);
assign R1_web= (NTT_busy ? NTT_R1_web : DOT_R1_web);
assign R2_wea= (NTT_busy ? NTT_R2_wea : DOT_R2_wea);
assign R2_web= (NTT_busy ? NTT_R2_web : DOT_R2_web);


assign R1_AddrAL = NTT_busy ? NTT_R1_AddrAL :DOT_R1_AddrAL;
assign R1_AddrBL = NTT_busy ? NTT_R1_AddrBL :DOT_R1_AddrBL;
assign R2_AddrAL = NTT_busy ? NTT_R2_AddrAL :DOT_R2_AddrAL;
assign R2_AddrBL = NTT_busy ? NTT_R2_AddrBL :DOT_R2_AddrBL;




//************************************************//

//******************  debug信号  *****************//
reg last_NTT_floor;
always@(posedge clk) begin
    last_NTT_floor <= NTT_floor;
    InFuncPrintRAM <= last_NTT_floor ^ NTT_floor;
end

assign Finish = NTT_Finish | Dot_Finish;

endmodule